package com.workerhelping.controller;

import com.workerhelping.config.OSSProperties;

import com.workerhelping.constant.MQConstant;
import com.workerhelping.dto.*;
import com.workerhelping.elasticsearchEntity.ESRecordVO;
import com.workerhelping.constant.ConstantEnum;
import com.workerhelping.enums.RecordStatusEnum;
import com.workerhelping.enums.StuckReasonEnum;
import com.workerhelping.feignClients.ESFeignClient;
import com.workerhelping.feignClients.MySQLFeignClient;
import com.workerhelping.feignClients.RabbitMQFeignClient;
import com.workerhelping.po.Confirm;
import com.workerhelping.po.Record;
import com.workerhelping.po.StuckReason;
import com.workerhelping.po.Worker;
import com.workerhelping.result.Result;
import com.workerhelping.result.ResultCodeEnum;
import com.workerhelping.utils.OSSUtil;
import com.workerhelping.vo.SubmitRecordVO;
import com.workerhelping.vo.WorkerConfirmVO;
import com.workerhelping.vo.WorkerPortalVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/record")
public class RecordController {

    @Autowired
    private MySQLFeignClient mySQLFeignClient;

    @Autowired
    private ESFeignClient esFeignClient;

    @Autowired
    private OSSProperties ossProperties;

    @Autowired
    private RabbitMQFeignClient rabbitMQFeignClient;

    /**
     * “我的档案”
     * 1. 查询职工档案状态是否存在
     * 2. 若不存在返回 208
     * 3. 复合查询档案信息
     *
     * @param session
     * @return
     */
    @PostMapping("/workerPortal")
    public Result<WorkerPortalVO> workerPortal(HttpSession session) {
        Object workerId = session.getAttribute(ConstantEnum.ID.getMsg());
        WorkerIdDTO workerIdDTO = new WorkerIdDTO(Integer.parseInt(workerId.toString()));
        Worker worker = mySQLFeignClient.getWorkerById(workerIdDTO).getData();
        session.setAttribute(ConstantEnum.STATUS.getMsg(), worker.getStatus());
        if (worker.getStatus().equals(RecordStatusEnum.UNSUBMITTED.getCode()))
            return Result.build(null, ResultCodeEnum.RECORD_IS_EMPTY);
        Result<WorkerPortalVO> result = mySQLFeignClient.getRecordWithWorkerById(workerIdDTO);
        return result;
    }

    /**
     * 点击“新建档案”，若存在档案，则拒绝
     *
     * @param session
     * @return
     */
    @GetMapping("/create")
    public Result<String> createRecord(HttpSession session) {
        Object statusObj = session.getAttribute(ConstantEnum.STATUS.getMsg());
        Integer status = Integer.parseInt(statusObj.toString());
//        if (status.equals(RecordStatusEnum.CANCELLED.getCode()))
//            return Result.build(null, ResultCodeEnum.record_already_logout);
        if (!status.equals(RecordStatusEnum.UNSUBMITTED.getCode()))
            return Result.build(null, ResultCodeEnum.RECORD_ALREADY_EXIST);
//        Result<List<StuckReason>> reasonResult = mySQLFeignClient.getAllStuckReasons();
//        if (reasonResult.isOk())
//            return Result.ok(reasonResult.getData());
       return Result.ok();
    }


    /**
     * 1. 文件单独上传
     * 2. oss上传文件返回地址
     * 3. 表单隐藏域存放地址
     *
     * @return
     */
    @PostMapping(value = "/uploadFile")
    public Result<String> uploadFile(@RequestParam(value = "file", required = false) MultipartFile multipartFile) throws IOException {
        if (multipartFile == null || multipartFile.isEmpty())
            return Result.build(null, ResultCodeEnum.FILE_IS_EMPTY);
        return OSSUtil.uploadFileToOss(
                ossProperties.getEndPoint(),
                ossProperties.getAccessKeyId(),
                ossProperties.getAccessKeySecret(),
                multipartFile.getInputStream(),
                ossProperties.getBucketName(),
                ossProperties.getBucketDomain(),
                multipartFile.getOriginalFilename());

    }


    /**
     * 提交档案表单
     * 1. 前端表单验证
     * 2. session获取职工id存入RecordPO
     * 3. 存入档案信息
     * 4. 设置WorkerDTO补全职工信息
     * 5. 更新致困原因、档案关系
     * 6. 更新es索引
     * <p>
     * ** 更新职工信息时将对应关系表字段清空
     *
     * @return
     */
    @PostMapping("/submit")
    public Result<String> submitRecord(@RequestBody SubmitRecordVO submitRecordVO, HttpSession session) {
        // session域获得职工id
        Object workerIdObj = session.getAttribute(ConstantEnum.ID.getMsg());
        Integer workerId = Integer.parseInt(workerIdObj.toString());
        Record record = new Record();
        BeanUtils.copyProperties(submitRecordVO, record);
        record.setWId(workerId);
        // 插入完整的档案对象，返回档案id
        Result<Integer> insertRecordResult = mySQLFeignClient.insertRecord(record);
        if (!insertRecordResult.isOk())
            return Result.fail();
        Integer recordId = insertRecordResult.getData();
        WorkerInfoDTO workerInfoDTO = new WorkerInfoDTO();
        workerInfoDTO.setId(workerId);
        workerInfoDTO.setCreateDate(new Date());
        // 改变档案状态为“未审核”
        workerInfoDTO.setStatus(RecordStatusEnum.UNREVIEWED.getCode());
        // 更新残缺的职工信息
        Result<String> workerInfoResult = mySQLFeignClient.updateWorkerInfo(workerInfoDTO);
        if (!workerInfoResult.isOk())
            return Result.fail();
        // 更新致困原因与档案的中间表
        StuckReasonIdsDTO stuckReasonIdsDTO = new StuckReasonIdsDTO(submitRecordVO.getStuckReasonIds(), recordId);
        Result<String> setRelationResult = mySQLFeignClient.setRecordStuckReasonsRelation(stuckReasonIdsDTO);
        if (!setRelationResult.isOk())
            return Result.fail();
        // 构造ESRecordVO 调用mq插入信息
        ESRecordVO esRecordVO = new ESRecordVO(recordId,
                submitRecordVO.getName(),
                submitRecordVO.getIdNumber(),
                submitRecordVO.getCreditCardNumbers(),
                RecordStatusEnum.UNREVIEWED.getStatus(),
                StuckReasonEnum.getStuckReasonName(submitRecordVO.getStuckReasonIds().get(0)),
                workerId);
        RabbitMQDTO rabbitMQDTO = new RabbitMQDTO(MQConstant.EXCHANGE_RECORD,
                MQConstant.ROUTINGKEY_RECORD_INSERTORUPDATE,
                esRecordVO);
        rabbitMQFeignClient.sendMsg(rabbitMQDTO);
        return Result.ok();
    }


    /**
     * 预览档案
     * @param session
     * @return
     */
    @PostMapping("/preview")
    public Result<SubmitRecordVO> previewRecord(HttpSession session) {
        // 获取workerId
        Object workerIdObj = session.getAttribute(ConstantEnum.ID.getMsg());
        int workerId = Integer.parseInt(workerIdObj.toString());
        // 根据WorkerId查询职员、档案信息
        WorkerIdDTO workerIdDTO = new WorkerIdDTO(workerId);
        Result<Record> recordResult = mySQLFeignClient.getRecordByWorkerId(workerIdDTO);
        if (!recordResult.isOk())
            return Result.fail();
        Record record = recordResult.getData();
        SubmitRecordVO submitRecordVO = new SubmitRecordVO();
        BeanUtils.copyProperties(record, submitRecordVO);
        RecordIdDTO recordIdDTO = new RecordIdDTO(record.getId());
        // 根据RecordId查询档案与致困原因中间表
        Result<List<Integer>> stuckReasonIdResult = mySQLFeignClient.getRecordStuckReasonByRecordId(recordIdDTO);
        if (!stuckReasonIdResult.isOk())
            return Result.fail();
        List<Integer> stuckReasonIdResultIds = stuckReasonIdResult.getData();
        List<Integer> stuckReasonIds_target = new ArrayList<>(stuckReasonIdResultIds);
        submitRecordVO.setStuckReasonIds(stuckReasonIds_target);
        return Result.ok(submitRecordVO);
    }


    /**
     * 页面回显数据
     * 隐藏域存储recordId
     *
     * @param session
     * @return
     */
    @PostMapping("/applyUpdateRecord")
    public Result<SubmitRecordVO> applyUpdateRecord(HttpSession session) {
        // 获取workerId
        Object workerIdObj = session.getAttribute(ConstantEnum.ID.getMsg());
        int workerId = Integer.parseInt(workerIdObj.toString());
        // 根据WorkerId查询职员、档案信息
        WorkerIdDTO workerIdDTO = new WorkerIdDTO(workerId);
        Result<Worker> workerResult = mySQLFeignClient.getWorkerById(workerIdDTO);
        Worker worker = workerResult.getData();
        if (worker.getStatus().equals(RecordStatusEnum.UNREVIEWED.getCode()))
            return Result.build(null, ResultCodeEnum.RECORD_NOT_AUDITED);
        else if (worker.getStatus().equals(RecordStatusEnum.CANCELLED.getCode()))
            return Result.build(null, ResultCodeEnum.RECORD_ALREADY_LOGOUT);
        Result<Record> recordResult = mySQLFeignClient.getRecordByWorkerId(workerIdDTO);
        if (!recordResult.isOk())
            return Result.fail();
        Record record = recordResult.getData();
        SubmitRecordVO submitRecordVO = new SubmitRecordVO();
        BeanUtils.copyProperties(record, submitRecordVO);
        RecordIdDTO recordIdDTO = new RecordIdDTO(record.getId());
        // 根据RecordId查询档案与致困原因中间表
        Result<List<Integer>> stuckReasonIdResult = mySQLFeignClient.getRecordStuckReasonByRecordId(recordIdDTO);
        if (!stuckReasonIdResult.isOk())
            return Result.fail();
        List<Integer> stuckReasonIdResultIds = stuckReasonIdResult.getData();
        List<Integer> stuckReasonIds_target = new ArrayList<>(stuckReasonIdResultIds);
        submitRecordVO.setStuckReasonIds(stuckReasonIds_target);
        return Result.ok(submitRecordVO);
    }

    /**
     * 更新档案信息
     *
     * @param submitRecordVO
     * @param session
     * @return
     */
    @PostMapping("/updateRecord")
    public Result<String> updateRecord(@RequestBody SubmitRecordVO submitRecordVO, HttpSession session) {
        Object workerIdObj = session.getAttribute(ConstantEnum.ID.getMsg());
        int workerId = Integer.parseInt(workerIdObj.toString());
        Integer recordId = submitRecordVO.getId();
        RecordIdDTO recordIdDTO = new RecordIdDTO(recordId);
        Record record = new Record();
        BeanUtils.copyProperties(submitRecordVO, record);
        Result<String> updateRecordResult = mySQLFeignClient.updateRecordByRecordId(record);
        if (!updateRecordResult.isOk())
            return Result.fail();
        Result<String> deleteResult = mySQLFeignClient.deleteRecordStuckReasonByRecordId(recordIdDTO);
        if (!deleteResult.isOk())
            return Result.fail();
        // 更新致困原因与档案的中间表
        StuckReasonIdsDTO stuckReasonIdsDTO = new StuckReasonIdsDTO(submitRecordVO.getStuckReasonIds(), recordId);
        Result<String> setRelationResult = mySQLFeignClient.setRecordStuckReasonsRelation(stuckReasonIdsDTO);
        if (!setRelationResult.isOk())
            return Result.fail();
        // 更新档案状态信息
        WorkerStatusInfoDTO workerStatusInfoDTO = new WorkerStatusInfoDTO(workerId, RecordStatusEnum.UNREVIEWED.getCode());
        Result<String> updateStatusResult = mySQLFeignClient.updateWorkerStatusInfo(workerStatusInfoDTO);
        if (!updateStatusResult.isOk())
            return Result.fail();
        ESRecordVO esRecordVO = new ESRecordVO(recordId,
                submitRecordVO.getName(),
                submitRecordVO.getIdNumber(),
                submitRecordVO.getCreditCardNumbers(),
                RecordStatusEnum.UNREVIEWED.getStatus(),
                StuckReasonEnum.getStuckReasonName(submitRecordVO.getStuckReasonIds().get(0)),
                workerId
        );
        RabbitMQDTO rabbitMQDTO = new RabbitMQDTO(MQConstant.EXCHANGE_RECORD,
                MQConstant.ROUTINGKEY_RECORD_INSERTORUPDATE,
                esRecordVO);
        rabbitMQFeignClient.sendMsg(rabbitMQDTO);
        return Result.ok();
    }

}
